/*******************************************************************************
 * FilePath    : \Software\Examples_Adv\adv_app_key\Src\BSP\WDG.c
 * Version     : 1.0
 * Brief       : 
 * Author      : AndrewHu
 * Company     : Shanghai MacroGiga Electronics CO.,Ltd
 * Email       : Hubinbo@macrogiga.com
 * Date        : 2020-04-03 15:06:14
 * LastEditors : AndrewHu
 * LastEditTime: 2021-04-20 11:54:12
 * Description : 
 ******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include <Includes.h>
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define IWDG_TEST_TIME (38400 * 11) //time 11S,LIR=38.4K
#define IWDG_MODE 0					//独立看门狗防呆
#define WWDG_MODE 1					//窗口看门狗防呆
#define SWDG_MODE 2					//软件防呆
#define WDG_MODE SWDG_MODE			//防呆选择
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
WWDG_HandleTypeDef wwdg_test = {0};
IWDG_HandleTypeDef iwdg_test = {0};
RTC_HandleTypeDef rtc_test = {0};
FlagStatus wwdg_int = RESET;
u32 SWDG_time = 0x00;
/* Private function ----------------------------------------------------------*/
/* extern --------------------------------------------------------------------*/
/*******************************************************************************
 * Function    : IWDG_Init
 * Brief       : 
 * Parameter   : 
 * Returns     : 
 * Date        : 2020-04-23 10:08:51
 * Description : 
 ******************************************************************************/
void IWDG_Init(void)
{
	RCC_OscInitTypeDef RCC_OscInitStruct = {0};

	RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LIRC;
	RCC_OscInitStruct.LIRCState = RCC_LIRC_ON;
	RCC_OscInitStruct.LIRCCalibrationValue = RCC_LIRCCALIBRATION_38K;

	if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
	{
		Error_Handler();
	}
	__HAL_RCC_IWDG_CLK_ENABLE();

	/*set init pa*/
	iwdg_test.Instance = IWDG;
	iwdg_test.Init.Reload = IWDG_TEST_TIME;

	iwdg_test.Init.MaskINT = IWDG_UNMASK_INT;
	iwdg_test.Init.Mode = IWDG_MODE_INT;

	/* Enable and set Button EXTI Interrupt to the lowest priority */
	HAL_NVIC_SetPriority(IWDG_IRQn, PRIORITY_LOW);
	HAL_NVIC_EnableIRQ(IWDG_IRQn);

	HAL_IWDG_Init(&iwdg_test);
}
/*******************************************************************************
 * Function    : WWDG_Init
 * Brief       : 
 * Parameter   : 
 * Returns     : 
 * Date        : 2020-03-23 14:55:30
 * Description : 窗口看门狗
 ******************************************************************************/
void WWDG_Init(void)
{
	__HAL_RCC_WWDG_CLK_ENABLE();

	/*set init */
	wwdg_test.Instance = WWDG;
	// wwdg_test.Init.Reload = 30; //time=43.8ms*(Reload-Window)
	wwdg_test.Init.Reload = 119; //time=43.8ms*(Reload-Window)
	wwdg_test.Init.Window = 0x05;
	wwdg_test.Init.Prescaler = 0xFFFFF; //43.8ms,PCLK=24M
	wwdg_test.Init.INTSet = WWDG_INT_ENABLE;
	/* Set interrupt priority and turn on interrupt*/
	HAL_NVIC_SetPriority(WWDG_IRQn, PRIORITY_LOW);
	HAL_NVIC_EnableIRQ(WWDG_IRQn);

	HAL_WWDG_Init(&wwdg_test);
}
/*******************************************************************************
 * Function    : SWDG_Init
 * Brief       : 软件计时初始化
 * Parameter   : 
 * Returns     : 
 * Date        : 2020-05-25 13:46:29
 * Description : 
 ******************************************************************************/
void SWDG_Init(void)
{
	RCC_OscInitTypeDef RCC_OscInitStruct = {0};

	//打开时钟
	RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LIRC;
	RCC_OscInitStruct.LIRCState = RCC_LIRC_ON;
	RCC_OscInitStruct.LIRCCalibrationValue = RCC_LIRCCALIBRATION_32K;

	if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
	{
		Error_Handler();
	}
	__HAL_RCC_RTC_CLK_ENABLE();

	//RTC 初始化
	rtc_test.Instance = RTC;
	rtc_test.Init.ClockSource = RTC_CLOCK_LIRC;			  //时钟源
	rtc_test.Init.HourFormat = RTC_HOURFORMAT_24;		  //时钟格式
	rtc_test.Init.TimeAdjustMode = RTC_TIME_ADJUST_SEC60; //隔多久校准一次
	rtc_test.Init.TimeTrim = 0x00;						  //校准值(-128~127)

	rtc_test.State = HAL_RTC_STATE_RESET;
	HAL_RTC_Init(&rtc_test);
	//设定中断时间
	HAL_RTC_Alarm2_Config(&rtc_test, ENABLE, (HAL_RTCAlarm2TypeDef)HAL_RTC_ALARM2_1S);

	/*Set interrupt priority and turn on interrupt*/
	HAL_NVIC_SetPriority(RTC_IRQn, PRIORITY_LOW);
	HAL_RTC_Alarm_INT_Config(&rtc_test, RTC_ALARM_2, ENABLE);
	HAL_RTC_Alarm_Clear_Flag(RTC_ALARM_2);
	HAL_NVIC_EnableIRQ(RTC_IRQn);
}
/*******************************************************************************
 * Function    : 计时重置
 * Brief       : SWDG_Refresh
 * Parameter   : 
 * Returns     : 
 * Date        : 2020-05-25 13:48:56
 * Description : 
 ******************************************************************************/
void SWDG_Refresh(void)
{
	SWDG_time = 0x00;
}
/*******************************************************************************
 * Function    : SWDG_Add
 * Brief       : 防呆计时累计
 * Parameter   : 
 * Returns     : 
 * Date        : 2020-05-28 18:24:29
 * Description : 
 ******************************************************************************/
void SWDG_Add(void)
{
	// if (GetRunningMode() == RunningMode_Standby)
	// 	SWDG_time = 0x00;
	// else
	SWDG_time++;
}
/*******************************************************************************
 * Function    : Get_SWDG_Time
 * Brief       : 返回防呆计时
 * Parameter   : 
 * Returns     : 
 * Date        : 2020-05-28 18:24:23
 * Description : 
 ******************************************************************************/
u32 Get_SWDG_Time(void)
{
	return SWDG_time;
}
/*******************************************************************************
 * Function    : WDG_Init
 * Brief       : 看门狗初始化
 * Parameter   : 
 * Returns     : 
 * Date        : 2020-04-23 10:13:55
 * Description : 
 ******************************************************************************/
void WDG_Init(void)
{
#if (WDG_MODE == IWDG_MODE)
	IWDG_Init();
#elif (WDG_MODE == WWDG_MODE)
	WWDG_Init();
#else
	SWDG_Init();
#endif
}
/*******************************************************************************
 * Function    : WDG_Mode_Set
 * Brief       : 
 * Parameter   : 
 * Returns     : 
 * Date        : 2020-04-23 10:21:23
 * Description : 
 ******************************************************************************/
void WDG_Mode_Set(IWDG_ModeTypeDef mode)
{
	iwdg_test.Init.Mode = mode;
	HAL_IWDG_Init(&iwdg_test);
	HAL_IWDG_Refresh(&iwdg_test);
}
/*******************************************************************************
 * Function    : HAL_WWDG_INT_Callback
 * Brief       : 
 * Parameter   : 
 * Returns     : 
 * Date        : 2020-03-23 16:32:42
 * Description : 清狗标志
 ******************************************************************************/
void HAL_WWDG_INT_Callback(void)
{
	wwdg_int = SET;
}
/*******************************************************************************
 * Function    : WDG_ReloadCounter
 * Brief       : 
 * Parameter   : 
 * Returns     : 
 * Date        : 2020-04-16 15:59:26
 * Description : 
 ******************************************************************************/
void WDG_ReloadCounter(void)
{
//窗口看门狗清狗
#if (WDG_MODE == IWDG_MODE)
	HAL_IWDG_Refresh(&iwdg_test);
#elif (WDG_MODE == WWDG_MODE)
	if (wwdg_int)
	{
		wwdg_int = RESET;
		HAL_WWDG_Refresh(&wwdg_test);
	}
#else
	SWDG_Refresh();
#endif
}
